using DOTS.DOD.LESSON0;
using Unity.Burst;
using Unity.Burst.Intrinsics;
using Unity.Collections;
using Unity.Entities;
using Unity.Transforms;

namespace DOTS.DOD.LESSON2
{
    [BurstCompile]
    struct RotateCubeWithIJobChunk : IJobChunk
    {
        public float DeltaTime;
        public ComponentTypeHandle<LocalTransform> TransformTypeHandle;
        [ReadOnly] public ComponentTypeHandle<RotateSpeed> RotateSpeedTypeHandle;

        public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask,
            in v128 chunkEnabledMask)
        {
            var chunk_transforms = chunk.GetNativeArray(ref TransformTypeHandle);
            var chunk_rotateSpeeds = chunk.GetNativeArray(ref RotateSpeedTypeHandle);

            var enumerator = new ChunkEntityEnumerator(useEnabledMask, chunkEnabledMask, chunk.Count);
            while (enumerator.NextEntityIndex(out var i))
            {
                var speed = chunk_rotateSpeeds[i];
                chunk_transforms[i] = chunk_transforms[i].RotateY(speed.Value * DeltaTime);
            }

            // for (int i = 0, chunkEntityCount = chunk.Count; i < chunkEntityCount; i++)
            // {
            //     var speed = chunk_rotateSpeeds[i];
            //     chunk_transforms[i] = chunk_transforms[i].RotateY(speed.Value * DeltaTime);
            // }
        }
    }


    [BurstCompile]
    [UpdateInGroup(typeof(CubeRotateWithIJobChunkSystemGroup))]
    public partial struct CubeRotateWithIJobChunkSystem : ISystem
    {
        EntityQuery mRotateCubes;
        ComponentTypeHandle<LocalTransform> mTransformTypeHandle;
        ComponentTypeHandle<RotateSpeed> mRotateSpeedTypeHandle;

        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            var queryBuilder = new EntityQueryBuilder(Allocator.Temp).WithAll<RotateSpeed, LocalTransform>();
            mRotateCubes = state.GetEntityQuery(queryBuilder);
            mTransformTypeHandle = state.GetComponentTypeHandle<LocalTransform>();
            mRotateSpeedTypeHandle = state.GetComponentTypeHandle<RotateSpeed>();
        }


        public void OnUpdate(ref SystemState state)
        {
            mTransformTypeHandle.Update(ref state);
            mRotateSpeedTypeHandle.Update(ref state);

            var job = new RotateCubeWithIJobChunk()
            {
                DeltaTime = SystemAPI.Time.DeltaTime,
                TransformTypeHandle = mTransformTypeHandle,
                RotateSpeedTypeHandle = mRotateSpeedTypeHandle,
            };
            //state.Dependency = job.Schedule(mRotateCubes, state.Dependency); //单线程
            state.Dependency = job.ScheduleParallel(mRotateCubes, state.Dependency); //多线程
        }
    }
}